<template>
  <div class="menu">
    <!-- 新增button -->
    <ui-button class="primary-btn mg-bt-20" icon="ui-icon-plus" @click="handleAdd">新增</ui-button>
    <!-- 表格 -->
    <vx-nodata sub-title="暂无数据" :list="menuList" v-loading="isLoading">
      <ui-table :data="menuList" row-key="id">
        <ui-table-column label="菜单名称" prop="name"> </ui-table-column>
        <ui-table-column label="菜单类型">
          <template v-slot="scope"> {{ $msg('menuTypeDict')[scope.row.type] }}</template>
        </ui-table-column>
        <ui-table-column label="icon">
          <template v-slot="scope">
            <i :class="`ui-icon-${scope.row.icon}`"></i>
          </template>
        </ui-table-column>
        <ui-table-column label="菜单路径" prop="component"> </ui-table-column>
        <ui-table-column label="按钮标识">
          <template v-slot="scope">
            {{ scope.row.type === 3 ? scope.row.component : '--' }}
          </template>
        </ui-table-column>
        <ui-table-column label="操作">
          <template v-slot="scope">
            <ui-button type="text" icon="ui-icon-edit" @click="handleEdit(scope.row)">编辑</ui-button>
            <ui-popover placement="top" width="160" :ref="`popover-${scope.$index}`">
              <p class="text-center mg-bt-10">确定删除吗?</p>
              <ui-button size="mini" type="danger" @click="handleClose(scope.$index)" class="mg-lt-20">取消</ui-button>
              <ui-button size="mini" type="primary" @click="menuRemove(scope.row.id)" :loading="isDelLoading">确定</ui-button>
              <ui-button slot="reference" icon="ui-icon-delete" class="mg-lt-10" type="text">删除</ui-button>
            </ui-popover>
          </template>
        </ui-table-column>
      </ui-table>
    </vx-nodata>
    <!-- 新增/编辑弹框 -->
    <vx-dialog
      :append-to-body="false"
      v-model="showAddDialog"
      :title="dialogTitle"
      auto-close
      @confirm="confirm"
      :loading="isBtnLoading"
      @cancel="isEditFlang = false"
      @handle-close="isEditFlang = false"
    >
      <ui-form ref="form" :rules="rules" label-width="150px" class="vx-form" label-position="right" :model="form">
        <ui-form-item label="菜单类型">
          <ui-radio-group v-model="form.type">
            <ui-radio :label="1" :disabled="isEditFlang && form.type !== 1">一级菜单</ui-radio>
            <ui-radio :label="2" :disabled="isEditFlang && form.type !== 2">子菜单</ui-radio>
            <ui-radio :label="3" :disabled="isEditFlang && form.type !== 3">按钮</ui-radio>
          </ui-radio-group>
        </ui-form-item>
        <ui-form-item label="菜单名称" v-if="form.type !== 3" prop="name">
          <ui-input placeholder="请输入菜单名称" v-model="form.name"></ui-input>
        </ui-form-item>
        <ui-form-item label="按钮名称" v-if="form.type === 3" prop="name">
          <ui-input placeholder="请输入按钮名称" v-model="form.name"></ui-input>
        </ui-form-item>
        <ui-form-item label="上级菜单" v-if="form.type === 2" prop="parentId">
          <ui-select placeholder="请选择上级菜单" v-model="form.parentId">
            <ui-option v-for="(item, index) in parentMenuList" :key="index" :value="item.id" :label="item.name"></ui-option>
          </ui-select>
        </ui-form-item>
        <ui-form-item label="上级菜单" v-if="form.type === 3" prop="parentId">
          <ui-select placeholder="请选择上级菜单" v-model="form.parentId">
            <ui-option
              v-for="(item, index) in childrenMenuList"
              :key="index"
              :value="item.id"
              :label="item.name === '用户管理' ? '用户管理(系统管理)' : item.name"
            ></ui-option>
          </ui-select>
        </ui-form-item>
        <ui-form-item :label="form.type === 3 ? '按钮标识' : '菜单路径'" prop="component">
          <ui-input placeholder="请输入菜单路径" v-model="form.component"></ui-input>
        </ui-form-item>
        <ui-form-item label="权限标识" v-if="form.type !== 1" prop="perms">
          <ui-input placeholder="请输入权限标识" v-model="form.perms" :disabled="isEditFlang"></ui-input>
        </ui-form-item>
        <ui-form-item label="状态" v-show="form.type === 3">
          <ui-switch v-model="form.enabled" :active-value="1" :inactive-value="0" active-text="有效" inactive-text="无效" :width="55" />
        </ui-form-item>
        <ui-form-item class="append-input-item" label="菜单图标" v-show="form.type === 1">
          <ui-input placeholder="点击右侧按钮选择图标或输入图标名" v-model="form.icon">
            <ui-button slot="append" @click="isIconDialog = true" :class="`ui-icon-${form.icon}`"></ui-button>
          </ui-input>
        </ui-form-item>
        <ui-form-item label="排序">
          <ui-input placeholder="请输入菜单排序" v-model="form.sort" type="number" :min="0"></ui-input>
        </ui-form-item>
      </ui-form>
    </vx-dialog>
    <!-- icon图标list -->
    <vx-icon-list @close="(val) => (isIconDialog = val)" :is-open="isIconDialog" @choose-icon="chooseIcon"></vx-icon-list>
  </div>
</template>

<script>
import menuApi from '@/api/menu.js';
import VxIconList from '@/components/vx-icon-list';

export default {
  name: 'menu-index',
  components: {
    VxIconList,
  },
  data() {
    return {
      menuList: undefined, //菜单列表
      parentMenuList: [], //一级菜单list
      childrenMenuList: [], //子菜单list
      isLoading: false, //表格加载loading
      isDelLoading: false, //删除确定按钮loading
      form: {
        type: 1, //菜单类型
        name: '', //菜单名称
        icon: 'setting', //icon名称-默认展示setting
        component: '', //组件
        url: '', //路径
        sort: '', //菜单排序
        enabled: 1, //按钮状态(0未开启，1开启）
        perms: '', //按钮权限标识
        parentId: '', //上级菜单id
      },
      showAddDialog: false, //是否展示增加菜单弹框
      isBtnLoading: false, //确定按钮loading
      rules: {
        name: [{ required: true, message: '请输入菜单名称', trigger: 'change' }],
        component: [{ required: true, message: '请输入菜单路径', trigger: 'change' }],
        parentId: [{ required: true, message: '请选择上级菜单', trigger: 'blur' }],
      },
      isIconDialog: false, //icon弹框展示
      isEditFlang: false, //是否是编辑操作
      dialogTitle: '', //弹窗title
    };
  },
  created() {
    this.menuListQry();
  },
  methods: {
    /**
     * 查询菜单列表
     */
    async menuListQry() {
      try {
        this.isLoading = true;
        const res = await menuApi.menuListQry();
        this.menuList = res.data || [];
        this.parentMenuList = this.menuList.filter((item) => item.type === 1); //所有一级菜单
        // 获取所有子菜单
        this.menuList.forEach((item) => {
          item.children &&
            item.children.forEach((i) => {
              if (item.name === '图标库管理' && i.name === '用户管理') {
                i.name = `${i.name}(${item.name})`;
              }
              // if (item.name === '系统管理' && i.name === '用户管理' && i.url === '/system/user') {
              //   i.name = `${i.name}(${item.name})`;
              // }
              this.childrenMenuList.push(i);
            });
        });
      } catch (error) {
        console.log(error);
      } finally {
        this.isLoading = false;
      }
    },
    /**
     * 关闭ui-popover弹窗
     * @param {Number} index 当前行
     */
    handleClose(index) {
      this.$refs[`popover-${index}`].doClose();
    },
    /**
     * 菜单删除操作
     * @param {Number} id 当前菜单id
     */
    async menuRemove(id) {
      try {
        this.isDelLoading = true;
        const res = await menuApi.menuRemove({ ids: id });
        this.$message.success(res.msg);
        this.menuListQry();
      } finally {
        this.isDelLoading = false;
      }
    },
    /**
     * 新增菜单
     */
    handleAdd() {
      this.form = {
        type: 1,
        name: '',
        icon: 'setting',
        component: '',
        url: '',
        sort: '',
        enabled: 1,
        perms: '',
        parentId: '',
      }; //初始化表单
      this.dialogTitle = '新增';
      this.showAddDialog = true;
    },
    /**
     * 编辑
     * @param {Object} row 选中行数据
     */
    handleEdit(row) {
      this.dialogTitle = '编辑';
      this.form = Object.assign({}, row);
      this.isEditFlang = true;
      this.showAddDialog = true;
    },
    /**
     * 弹框确定提交
     */
    async confirm() {
      // 编辑操作提交时
      if (this.isEditFlang) {
        try {
          this.isBtnLoading = true;
          const res = await menuApi.menuEdit(this.form);
          this.$message.success(res.msg);
          this.menuListQry();
          this.showAddDialog = false; //关闭弹窗
          this.isEditFlang = false; //关闭编辑标识
        } catch (err) {
          this.$message.error(err.message);
        } finally {
          this.isBtnLoading = false;
        }
      } else {
        // 新增操作提交时
        this.$refs['form'].validate(async (valid) => {
          // 表单校验通过
          if (valid) {
            try {
              this.isBtnLoading = true;
              // 必传的参数
              let params = {
                name: this.form.name,
                url: this.form.url,
                type: this.form.type,
                menuCode: 'page', //写死上送
              };
              // 一级菜单需上送的参数
              if (this.form.type === 1) {
                let obj = {
                  component: this.form.component,
                  sort: this.form.sort,
                  icon: this.form.icon,
                  parentId: '0', //一级菜单时固定传'0'
                };
                params = { ...obj, ...params };
                // 子菜单需要上送的参数
              } else if (this.form.type === 2) {
                let obj = {
                  component: this.form.component,
                  sort: this.form.sort,
                  parentId: this.form.parentId,
                };
                params = { ...obj, ...params };
              } else {
                let obj = {
                  sort: this.form.sort,
                  parentId: this.form.parentId,
                  perms: this.form.perms, //权限标识
                  component: this.form.component,
                  enabled: this.form.enabled, //状态
                };
                params = { ...obj, ...params };
              }
              const res = await menuApi.menuAdd(params);
              this.$message.success(res.msg);
              this.menuListQry();
              this.showAddDialog = false;
            } finally {
              this.isBtnLoading = false;
            }
          } else {
            this.$nextTick(() => {
              document
                .querySelectorAll('.is-error')[0]
                .querySelector('input')
                .focus();
            });
          }
        });
      }
    },

    /**
     * 获取选中的icon图标
     * @param {String} iconName 选中的icon图标名字
     */
    chooseIcon(iconName) {
      this.form.icon = iconName;
      this.isIconDialog = false;
    },
  },
};
</script>

<style lang="scss">
.menu {
  .ui-icon-plus {
    color: #fff;
  }
  .vx-dialog {
    .ui-dialog__body {
      .vx-form {
        .append-input-item {
          .ui-input__inner {
            width: 256px;
          }
        }
      }
    }
  }
}
</style>
